<template>
  <el-card class="my-recorder" v-loading="loading">
    <div slot="header" class="clearfix">
      <span>{{ msg }}</span>
    </div>
    <el-descriptions>
      <el-descriptions-item :label="recorderFieldTips">{{
        recorderText
        }}</el-descriptions-item>
    </el-descriptions>
    <el-row>
      <el-col>
        <h3 v-if="recorderStatus < 3">
          录音时长：{{ recorder && recorder.duration.toFixed(4) }}
        </h3>
        <h3 v-if="recorderStatus >= 3">
          播放时长：{{
          recorder &&
          (playTime > recorder.duration
          ? recorder.duration.toFixed(4)
          : playTime.toFixed(4))
          }}
        </h3>
        {{ recorderStatus }}
        <el-col>
          <!-- 录音图 -->
          <canvas id="canvas" v-show="recorderStatus < 3" />
          <!-- 播放图 -->
          <audio v-show="recorderEnd != null && recorderStatus>= 3" controls ref="audio" muted="muted" src=""
            id="audio" />
          <el-empty description="暂无录音内容" v-if="!recorderStatus" />
        </el-col>
        <!-- 开始录音 || 重新录音 -->
        <el-button type="primary" @click="startRecorder"
          v-if="!recorderStatus || recorderStatus === 3 || recorderStatus === 6">{{
          recorderStatus === 3 || recorderStatus === 6
          ? '重新录音'
          : '开始录音'
          }}</el-button>
        <!-- 暂停录音 -->
        <el-button type="info" @click="pauseRecorder" v-if="recorderStatus === 1">暂停录音</el-button>
        <!-- 继续录音 -->
        <el-button type="success" @click="resumeRecorder" v-if="recorderStatus === 2">继续录音</el-button>
        <!-- 停止录音 -->
        <el-button type="warning" @click="stopRecorder" v-if="
            recorderStatus !== 0 && recorderStatus !== 3 && recorderStatus < 3
          ">结束录音</el-button>
        <!-- 上传录音 -->
        <el-button type="success" @click="sendRecorder"
          v-if="recorderStatus === 3 && recorderStatus !== 6">上传录音</el-button>
        <!-- <el-button type="error" @click="destroyRecorder" 
              >销毁录音</el-button
            > -->
        <!-- <el-button type="primary" @click="uploadRecord">上传</el-button>
            <el-button type="primary" @click="downPCM">下载PCM数据</el-button> -->
        <!-- <el-button type="primary" @click="downWAV">下载WAV数据</el-button> -->
      </el-col>
    </el-row>
  </el-card>
</template>

<script>
import Recorder from 'js-audio-recorder';
import instructionsJson from '@/assets/json/instructions.json';

// import axios from 'axios'
export default {
  name: 'MyRecorder',
  props: {
    msg: String,
  },
  data () {
    return {
      loading: false,
      recorder: null,
      playTime: 0,
      timer: null,
      src: null,
      //波浪图-录音
      drawRecordId: null,
      oCanvas: null,
      ctx: null,
      //波浪图-播放
      drawPlayId: null,
      pCanvas: null,
      pCtx: null,
      // 播放器
      audioDialog: false,
      recoderSecond: 0,
      recorderEnd: null,
      recorderSourceData: [],
      recorderStatus: 0, // 0 为未录音 1为录音中 2为暂停录音中 3为已停止录音 4为正在播放 5为暂停播放中 6为已停止播放
      recorderTimes: 1, // 录取的次数
    };
  },
  created () {
    console.log(this.$route.query);
    this.recorderSourceData = this.groupBy(instructionsJson, 70);
    console.log(this.recorderSourceData);
    this.recorder = new Recorder({
      sampleBits: 16, // 采样位数，支持 8 或 16，默认是 16
      sampleRate: 44100, // 采样率，支持 11025、16000、22050、24000、44100、48000，根据浏览器默认值，Chrome 是 48000
      numChannels: 1, // 声道数，支持 1 或 2， 默认是 1
    });
  },
  mounted () {
    this.startCanvas();
    setTimeout(() => {
      this.loading = false;
    }, 1500);
  },
  computed: {
    recorderFieldTips () {
      if (this.recorderTimes === 1) return '请以正常语速读此文字';
      return '请以快语速读此文字';
    },
    recorderText () {
      const label =
        this.recorderSourceData[parseInt(this.$route.query.number) - 1][0]
          .label;
      return (
        label ||
        this.recorderSourceData[parseInt(this.$route.query.number) - 1][1].label // 因为数据中有一条假数据，以适应每人70条数据
      );
    },
  },
  methods: {
    // 按70个数组分组
    groupBy (array, groupSize) {
      return array.reduce((result, value, index) => {
        const chunkIndex = Math.floor(index / groupSize);
        if (!result[chunkIndex]) {
          result[chunkIndex] = [];
        }
        result[chunkIndex].push(value);
        return result;
      }, []);
    },
    /**
     * 波浪图配置
     * */
    startCanvas () {
      //录音波浪
      this.oCanvas = document.getElementById('canvas');
      this.ctx = this.oCanvas.getContext('2d');
    },
    /**
     *  录音的具体操作功能
     * */
    // 开始录音
    startRecorder () {
      if (this.recorder) {
        this.recorder.destroy();
        this.recorder = null;
      }
      let _this = this;
      Recorder.getPermission().then(
        () => {
          _this.recorderStatus = 1;
          _this.recorder = new Recorder();
          _this.recorderAudio = document.querySelector('#audio');
          console.log('开始录音');
          this.recorder.start().then(
            () => {
              this.drawRecord(); //开始绘制图片
            },
            (error) => {
              // 出错了
              console.log(`${error.name} : ${error.message}`);
            }
          );
        },
        (error) => {
          this.$message({
            message: '请先允许该网页使用麦克风',
            type: 'info',
          });
          console.log(`${error.name} : ${error.message}`);
        }
      );
    },
    // 暂停录音
    pauseRecorder () {
      console.log('暂停录音');
      this.recorder.pause(); // 暂停录音
      this.drawRecordId && cancelAnimationFrame(this.drawRecordId);
      this.drawRecordId = null;
      this.recorderStatus = 2;
    },
    // 继续录音
    resumeRecorder () {
      console.log('恢复录音');
      this.recorder.resume(); // 恢复录音
      this.drawRecord(); // 恢复绘制波浪图
      this.recorderStatus = 1;
    },
    // 结束录音
    stopRecorder () {
      if (!this.recorder) {
        return;
      }
      let blob = this.recorder.getWAVBlob();
      this.recorderAudio.src = URL.createObjectURL(blob);
      this.recorderAudio.controls = true;
      this.recorderEnd = blob;
      this.recorderStatus = 3;
      let _this = this;
      this.recorder.destroy().then(function () {
        _this.recorder = null;
        _this.drawRecordId && cancelAnimationFrame(_this.drawRecordId);
        _this.drawRecordId = null;
      });
    },
    /**
     *  下载录音文件
     * */
    //下载pcm
    downPCM () {
      console.log('下载PCM格式数据');
      // 注：使用该方法会默认调用 stop() 方法
      this.recorder.downloadPCM('record-pcm');
    },
    //下载wav
    downWAV () {
      console.log('下载WAV格式数据');
      // 注：使用该方法会默认调用 stop() 方法
      this.recorder.downloadWAV('record-wav');
    },
    //发送录音
    sendRecorder () {
      this.sendRecorder();
      if (!this.recorderEnd) return;

      let _this = this;
      let formData = new FormData();
      formData.append('realfile', this.recorderEnd); //传给后台的file的key值是可以自己定义的
      fetch(_this.ApiHost + '/2/uploadAudio', {
        method: 'POST',
        body: formData,
      })
        .then((response) => response.json())
        .then((res) => {
          console.log(res);
          if (res.code != 200) {
            _this.$message({
              message: res.msg,
              type: 'error',
            });
          } else {
            _this.$message({
              message: 'success！',
              type: 'success',
            });
            _this.cancelRecoder();
            _this.visitor.message = 'audio[' + res.result.path + ']';
            _this.chatToUser();
          }
        })
        .catch((error) => {
          console.error(error);
        });
    },
    /**
     * 文件格式转换 wav-map3
     * */
    getMp3Data () {
      const mp3Blob = this.convertToMp3(this.recorder.getWAV());
      this.recorder.download(mp3Blob, 'recorder', 'mp3');
    },
    /**
     * 绘制波浪图-录音
     * */
    drawRecord () {
      // 用requestAnimationFrame稳定60fps绘制
      this.drawRecordId = requestAnimationFrame(this.drawRecord);
      // 实时获取音频大小数据
      let dataArray = this.recorder.getRecordAnalyseData(),
        bufferLength = dataArray.length;
      // 填充背景色
      this.ctx.fillStyle = 'rgb(200, 200, 200)';
      this.ctx.fillRect(0, 0, this.oCanvas.width, this.oCanvas.height);
      // 设定波形绘制颜色
      this.ctx.lineWidth = 2;
      this.ctx.strokeStyle = 'rgb(0, 0, 0)';
      this.ctx.beginPath();
      var sliceWidth = (this.oCanvas.width * 1.0) / bufferLength, // 一个点占多少位置，共有bufferLength个点要绘制
        x = 0; // 绘制点的x轴位置
      for (var i = 0; i < bufferLength; i++) {
        var v = dataArray[i] / 128.0;
        var y = (v * this.oCanvas.height) / 2;
        if (i === 0) {
          // 第一个点
          this.ctx.moveTo(x, y);
        } else {
          // 剩余的点
          this.ctx.lineTo(x, y);
        }
        // 依次平移，绘制所有点
        x += sliceWidth;
      }
      this.ctx.lineTo(this.oCanvas.width, this.oCanvas.height / 2);
      this.ctx.stroke();
    },
  },
};
</script>
<style lang="scss" scoped>
.my-recorder {
  margin: 20px;

  h3 {
    margin-bottom: 20px;
  }

  .el-col {
    margin: 20px 0;
  }
}
</style>
